//最新代码，以 https://gitee.com/yiliangwu880/CppProto.git 项目为准。

#pragma once
#include "log_def.h"
#include <string>
#include <string.h>
#include <vector>
#include <functional>
#include <unordered_map>
#include <map>
#include <stdint.h>

#define MAKE_ARG_LIST_1(op, arg, ...)   op(arg)
#define MAKE_ARG_LIST_2(op, arg, ...)   op(arg) MARCO_EXPAND(MAKE_ARG_LIST_1(op, __VA_ARGS__))
#define MAKE_ARG_LIST_3(op, arg, ...)   op(arg) MARCO_EXPAND(MAKE_ARG_LIST_2(op, __VA_ARGS__))
#define MAKE_ARG_LIST_4(op, arg, ...)   op(arg) MARCO_EXPAND(MAKE_ARG_LIST_3(op, __VA_ARGS__))
#define MAKE_ARG_LIST_5(op, arg, ...)   op(arg) MARCO_EXPAND(MAKE_ARG_LIST_4(op, __VA_ARGS__))
#define MAKE_ARG_LIST_6(op, arg, ...)   op(arg) MARCO_EXPAND(MAKE_ARG_LIST_5(op, __VA_ARGS__))
#define MAKE_ARG_LIST_7(op, arg, ...)   op(arg) MARCO_EXPAND(MAKE_ARG_LIST_6(op, __VA_ARGS__))
#define MAKE_ARG_LIST_8(op, arg, ...)   op(arg) MARCO_EXPAND(MAKE_ARG_LIST_7(op, __VA_ARGS__))
#define MAKE_ARG_LIST_9(op, arg, ...)   op(arg) MARCO_EXPAND(MAKE_ARG_LIST_8(op, __VA_ARGS__))
#define MAKE_ARG_LIST_10(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_9(op, __VA_ARGS__))
#define MAKE_ARG_LIST_11(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_10(op, __VA_ARGS__))
#define MAKE_ARG_LIST_12(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_11(op, __VA_ARGS__))
#define MAKE_ARG_LIST_13(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_12(op, __VA_ARGS__))
#define MAKE_ARG_LIST_14(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_13(op, __VA_ARGS__))
#define MAKE_ARG_LIST_15(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_14(op, __VA_ARGS__))
#define MAKE_ARG_LIST_16(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_15(op, __VA_ARGS__))
#define MAKE_ARG_LIST_17(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_16(op, __VA_ARGS__))
#define MAKE_ARG_LIST_18(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_17(op, __VA_ARGS__))
#define MAKE_ARG_LIST_19(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_18(op, __VA_ARGS__))
#define MAKE_ARG_LIST_20(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_19(op, __VA_ARGS__))
#define MAKE_ARG_LIST_21(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_20(op, __VA_ARGS__))
#define MAKE_ARG_LIST_22(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_21(op, __VA_ARGS__))
#define MAKE_ARG_LIST_23(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_22(op, __VA_ARGS__))
#define MAKE_ARG_LIST_24(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_23(op, __VA_ARGS__))
#define MAKE_ARG_LIST_25(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_24(op, __VA_ARGS__))
#define MAKE_ARG_LIST_26(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_25(op, __VA_ARGS__))
#define MAKE_ARG_LIST_27(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_26(op, __VA_ARGS__))
#define MAKE_ARG_LIST_28(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_27(op, __VA_ARGS__))
#define MAKE_ARG_LIST_29(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_28(op, __VA_ARGS__))
#define MAKE_ARG_LIST_30(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_29(op, __VA_ARGS__))
#define MAKE_ARG_LIST_31(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_30(op, __VA_ARGS__))
#define MAKE_ARG_LIST_32(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_31(op, __VA_ARGS__))
#define MAKE_ARG_LIST_33(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_32(op, __VA_ARGS__))
#define MAKE_ARG_LIST_34(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_33(op, __VA_ARGS__))
#define MAKE_ARG_LIST_35(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_34(op, __VA_ARGS__))
#define MAKE_ARG_LIST_36(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_35(op, __VA_ARGS__))
#define MAKE_ARG_LIST_37(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_36(op, __VA_ARGS__))
#define MAKE_ARG_LIST_38(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_37(op, __VA_ARGS__))
#define MAKE_ARG_LIST_39(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_38(op, __VA_ARGS__))
#define MAKE_ARG_LIST_40(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_39(op, __VA_ARGS__))
#define MAKE_ARG_LIST_41(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_40(op, __VA_ARGS__))
#define MAKE_ARG_LIST_42(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_41(op, __VA_ARGS__))
#define MAKE_ARG_LIST_43(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_42(op, __VA_ARGS__))
#define MAKE_ARG_LIST_44(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_43(op, __VA_ARGS__))
#define MAKE_ARG_LIST_45(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_44(op, __VA_ARGS__))
#define MAKE_ARG_LIST_46(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_45(op, __VA_ARGS__))
#define MAKE_ARG_LIST_47(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_46(op, __VA_ARGS__))
#define MAKE_ARG_LIST_48(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_47(op, __VA_ARGS__))
#define MAKE_ARG_LIST_49(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_48(op, __VA_ARGS__))
#define MAKE_ARG_LIST_50(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_49(op, __VA_ARGS__))
#define MAKE_ARG_LIST_51(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_50(op, __VA_ARGS__))
#define MAKE_ARG_LIST_52(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_51(op, __VA_ARGS__))
#define MAKE_ARG_LIST_53(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_52(op, __VA_ARGS__))
#define MAKE_ARG_LIST_54(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_53(op, __VA_ARGS__))
#define MAKE_ARG_LIST_55(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_54(op, __VA_ARGS__))
#define MAKE_ARG_LIST_56(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_55(op, __VA_ARGS__))
#define MAKE_ARG_LIST_57(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_56(op, __VA_ARGS__))
#define MAKE_ARG_LIST_58(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_57(op, __VA_ARGS__))
#define MAKE_ARG_LIST_59(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_58(op, __VA_ARGS__))
#define MAKE_ARG_LIST_60(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_59(op, __VA_ARGS__))
#define MAKE_ARG_LIST_61(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_60(op, __VA_ARGS__))
#define MAKE_ARG_LIST_62(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_61(op, __VA_ARGS__))
#define MAKE_ARG_LIST_63(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_62(op, __VA_ARGS__))
#define MAKE_ARG_LIST_64(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_63(op, __VA_ARGS__))
#define MAKE_ARG_LIST_65(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_64(op, __VA_ARGS__))
#define MAKE_ARG_LIST_66(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_65(op, __VA_ARGS__))
#define MAKE_ARG_LIST_67(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_66(op, __VA_ARGS__))
#define MAKE_ARG_LIST_68(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_67(op, __VA_ARGS__))
#define MAKE_ARG_LIST_69(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_68(op, __VA_ARGS__))
#define MAKE_ARG_LIST_70(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_69(op, __VA_ARGS__))
#define MAKE_ARG_LIST_71(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_70(op, __VA_ARGS__))
#define MAKE_ARG_LIST_72(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_71(op, __VA_ARGS__))
#define MAKE_ARG_LIST_73(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_72(op, __VA_ARGS__))
#define MAKE_ARG_LIST_74(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_73(op, __VA_ARGS__))
#define MAKE_ARG_LIST_75(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_74(op, __VA_ARGS__))
#define MAKE_ARG_LIST_76(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_75(op, __VA_ARGS__))
#define MAKE_ARG_LIST_77(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_76(op, __VA_ARGS__))
#define MAKE_ARG_LIST_78(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_77(op, __VA_ARGS__))
#define MAKE_ARG_LIST_79(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_78(op, __VA_ARGS__))
#define MAKE_ARG_LIST_80(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_79(op, __VA_ARGS__))
#define MAKE_ARG_LIST_81(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_80(op, __VA_ARGS__))
#define MAKE_ARG_LIST_82(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_81(op, __VA_ARGS__))
#define MAKE_ARG_LIST_83(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_82(op, __VA_ARGS__))
#define MAKE_ARG_LIST_84(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_83(op, __VA_ARGS__))
#define MAKE_ARG_LIST_85(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_84(op, __VA_ARGS__))
#define MAKE_ARG_LIST_86(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_85(op, __VA_ARGS__))
#define MAKE_ARG_LIST_87(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_86(op, __VA_ARGS__))
#define MAKE_ARG_LIST_88(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_87(op, __VA_ARGS__))
#define MAKE_ARG_LIST_89(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_88(op, __VA_ARGS__))
#define MAKE_ARG_LIST_90(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_89(op, __VA_ARGS__))
#define MAKE_ARG_LIST_91(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_90(op, __VA_ARGS__))
#define MAKE_ARG_LIST_92(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_91(op, __VA_ARGS__))
#define MAKE_ARG_LIST_93(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_92(op, __VA_ARGS__))
#define MAKE_ARG_LIST_94(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_93(op, __VA_ARGS__))
#define MAKE_ARG_LIST_95(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_94(op, __VA_ARGS__))
#define MAKE_ARG_LIST_96(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_95(op, __VA_ARGS__))
#define MAKE_ARG_LIST_97(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_96(op, __VA_ARGS__))
#define MAKE_ARG_LIST_98(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_97(op, __VA_ARGS__))
#define MAKE_ARG_LIST_99(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_98(op, __VA_ARGS__))
#define MAKE_ARG_LIST_100(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_99(op, __VA_ARGS__))
#define MAKE_ARG_LIST_101(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_100(op, __VA_ARGS__))
#define MAKE_ARG_LIST_102(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_101(op, __VA_ARGS__))
#define MAKE_ARG_LIST_103(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_102(op, __VA_ARGS__))
#define MAKE_ARG_LIST_104(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_103(op, __VA_ARGS__))
#define MAKE_ARG_LIST_105(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_104(op, __VA_ARGS__))
#define MAKE_ARG_LIST_106(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_105(op, __VA_ARGS__))
#define MAKE_ARG_LIST_107(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_106(op, __VA_ARGS__))
#define MAKE_ARG_LIST_108(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_107(op, __VA_ARGS__))
#define MAKE_ARG_LIST_109(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_108(op, __VA_ARGS__))
#define MAKE_ARG_LIST_110(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_109(op, __VA_ARGS__))
#define MAKE_ARG_LIST_111(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_110(op, __VA_ARGS__))
#define MAKE_ARG_LIST_112(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_111(op, __VA_ARGS__))
#define MAKE_ARG_LIST_113(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_112(op, __VA_ARGS__))
#define MAKE_ARG_LIST_114(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_113(op, __VA_ARGS__))
#define MAKE_ARG_LIST_115(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_114(op, __VA_ARGS__))
#define MAKE_ARG_LIST_116(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_115(op, __VA_ARGS__))
#define MAKE_ARG_LIST_117(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_116(op, __VA_ARGS__))
#define MAKE_ARG_LIST_118(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_117(op, __VA_ARGS__))
#define MAKE_ARG_LIST_119(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_118(op, __VA_ARGS__))
#define MAKE_ARG_LIST_120(op, arg, ...)  op(arg) MARCO_EXPAND(MAKE_ARG_LIST_119(op, __VA_ARGS__))

#define RSEQ_N() \
         119,118,117,116,115,114,113,112,111,110,\
         109,108,107,106,105,104,103,102,101,100,\
         99,98,97,96,95,94,93,92,91,90, \
         89,88,87,86,85,84,83,82,81,80, \
         79,78,77,76,75,74,73,72,71,70, \
         69,68,67,66,65,64,63,62,61,60, \
         59,58,57,56,55,54,53,52,51,50, \
         49,48,47,46,45,44,43,42,41,40, \
         39,38,37,36,35,34,33,32,31,30, \
         29,28,27,26,25,24,23,22,21,20, \
         19,18,17,16,15,14,13,12,11,10, \
         9,8,7,6,5,4,3,2,1,0

#define ARG_N(\
         _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, \
         _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, \
         _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, \
         _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, \
         _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, \
         _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, \
         _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, \
         _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, \
         _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, \
         _91, _92, _93, _94, _95, _96, _97, _98, _99, _100, \
         _101, _102, _103, _104, _105, _106, _107, _108, _109, _110, \
         _111, _112, _113, _114, _115, _116, _117, _118, _119, N, ...) N

#define MARCO_EXPAND(...)                 __VA_ARGS__
#define APPLY_VARIADIC_MACRO(macro, ...)  MARCO_EXPAND(macro(__VA_ARGS__))

//note use MACRO_CONCAT like A##_##B direct may cause marco expand error
#define MACRO_CONCAT(A, B) MACRO_CONCAT1(A, B)
#define MACRO_CONCAT1(A, B) A##_##B

//变为  op(arg1), op(arg2), ... op(argN)
#define MAKE_ARG_LIST(op, ...)  MACRO_CONCAT(MAKE_ARG_LIST, GET_ARG_COUNT(__VA_ARGS__))(op, __VA_ARGS__)

#define GET_ARG_COUNT_INNER(...)    MARCO_EXPAND(ARG_N(__VA_ARGS__))
#define GET_ARG_COUNT(...)          GET_ARG_COUNT_INNER(__VA_ARGS__, RSEQ_N())
/////////////////////////////////////////////////////////////////////////////


namespace proto
{
	using PointChar = char*;
	using CPointChar = const char*;

	struct StaticRunFun
	{
		StaticRunFun(std::function<void(void)> f)
		{
			f();
		}
	};

	//原生包数据， 表示调用proto::pack 函数产生的字符串。 
	//通常用来转发参数用。不需要unpack具体参数。
	class RawPackStr : public std::string
	{
	};

	//@cur [in]打包到内存地址，[out]第一个未使用的内存地址（下个变量打包的内存地址）。
	//@len [in]cur 有效长度，[out]打包后，cur未使用字节长度
	template<class T>
	inline bool Pack(const T& t, PointChar& cur, size_t& len)
	{
		L_ERROR("pack unknow. type name = %s", typeid(T).name());
		static_assert(!(&t), "miss define REFLECTION for T");
		return false;
	}
	//@cur [in]解包来源内存地址，[out]第一个未解包的内存地址（下个变量解包的内存地址）。
	//@len [in]cur有效长度，[out]解包后，cur未使用字节长度
	template<class T>
	inline bool Unpack(T& t, CPointChar& cur, size_t& len)
	{
		L_ERROR("unpack unknow. type name = %s", typeid(T).name());
		static_assert(!(&t), "miss define REFLECTION for T");
		return false;
	}
	template<class T>
	inline bool Pack(const T& t, std::string& str)
	{
		L_ERROR("pack unknow. type name = %s", typeid(T).name());
		static_assert(!(&t), "miss define REFLECTION for T");
		return false;
	}
	template<class T>
	inline bool Unpack(T& t, const std::string& str)
	{
		L_ERROR("unpack unknow. type name = %s", typeid(T).name());
		static_assert(!(&t), "miss define REFLECTION for T");
		return false;
	}
	//解包消息ID用，例如 const uint16_t id = 1; 
	//比较cmdId 是否一样
	template<>
	inline bool Unpack<const uint16_t>(const uint16_t& v, CPointChar& cur, size_t& len)
	{
		L_COND(len >= sizeof(v), false);
		uint16_t unpackV = *(uint16_t*)cur;
		cur += sizeof(v);
		len -= sizeof(v);
		L_COND(v == unpackV, false, "unpack struct type id is wrong. need id=%d, rev id=%d", v, unpackV); //解包内容和对象不符合。  消息ID不一样
		return true;
	}


#define EASY_CODE(T)\
	template<>\
	inline bool Pack<T>(const T &v, PointChar &cur, size_t &len)\
	{\
		L_COND(len >= sizeof(v), false);\
		*(T*)cur = v;\
		cur += sizeof(v);\
		len -= sizeof(v);\
		return true;\
	}\

	EASY_CODE(bool)
	EASY_CODE(int32_t)
	EASY_CODE(uint32_t)
	EASY_CODE(int64_t)
	EASY_CODE(uint64_t)
	EASY_CODE(double)
	EASY_CODE(int16_t)
	EASY_CODE(uint16_t)
	EASY_CODE(int8_t)
	EASY_CODE(char)
	EASY_CODE(uint8_t)
#undef  EASY_CODE

#define EASY_CODE(T)\
	template<>\
	inline bool Unpack<T>(T &v, CPointChar &cur, size_t &len)\
	{\
		L_COND(len >= sizeof(v), false);\
		v = *(T*)cur;\
		cur += sizeof(v);\
		len -= sizeof(v);\
		return true;\
	}\

		EASY_CODE(bool)
		EASY_CODE(int32_t)
		EASY_CODE(uint32_t)
		EASY_CODE(int64_t)
		EASY_CODE(uint64_t)
		EASY_CODE(double)
		EASY_CODE(int16_t)
		EASY_CODE(uint16_t)
		EASY_CODE(int8_t)
		EASY_CODE(char)
		EASY_CODE(uint8_t)
#undef  EASY_CODE

	template<>
	inline bool Pack<std::string>(const std::string& v, PointChar& cur, size_t& len)
	{
		uint32_t strLen = v.length();
		L_COND(Pack(strLen, cur, len), false);
		L_COND(len >= strLen, false);
		memcpy(cur, v.c_str(), strLen);
		cur += strLen;
		len -= strLen;
		return true;
	}
	template<>
	inline bool Pack<CPointChar>(const CPointChar& v, PointChar& cur, size_t& len)
	{
		uint32_t strLen = strlen(v);
		L_COND(Pack(strLen, cur, len), false);
		L_COND(len >= strLen, false);
		memcpy(cur, v, strLen);
		cur += strLen;
		len -= strLen;
		return true;
	}
	template<>
	inline bool Unpack<std::string>(std::string& v, CPointChar& cur, size_t& len)
	{
		uint32_t strLen;
		L_COND(Unpack(strLen, cur, len), false);
		L_COND(len >= strLen, false, "%ld > %d", len, strLen);
		v.assign(cur, strLen);
		cur += strLen;
		len -= strLen;
		return true;
	}
	
	template<>
	inline bool Pack<RawPackStr>(const RawPackStr& v, PointChar& cur, size_t& len)
	{
		uint32_t strLen = v.length();
		L_COND(len >= strLen, false);
		memcpy(cur, v.c_str(), strLen);
		cur += strLen;
		len -= strLen;
		return true;
	}
	template<>
	inline bool Unpack<RawPackStr>(RawPackStr& v, CPointChar& cur, size_t& len)
	{
		uint32_t strLen = len;
		v.assign(cur, strLen);
		cur += strLen;
		len -= strLen;
		return true;
	}

	template<class Vec>
	inline bool PackVector(const Vec& v, PointChar& cur, size_t& len)
	{
		using ElementType = typename Vec::value_type;
		uint32_t vecLen = v.size();
		L_COND(Pack(vecLen, cur, len), false);
		if constexpr (std::is_class<ElementType>::value)
		{
			for (const auto& vt : v)
			{
				L_COND(Pack(vt, cur, len), false);
			}
		}
		else//基础类型，整块内存复制. 不优化效率比优化效率， 比例：  0.0065ms ： 0.0053ms
		{
			if (vecLen > 0)
			{
				const size_t vecByteNum = sizeof(ElementType) * vecLen;
				L_COND(len >= vecByteNum, false);
				memcpy(cur, &v[0], vecByteNum);
				cur += vecByteNum;
				len -= vecByteNum;
			}
		}
		return true;
	}

	template<class Vec>
	inline bool UnpackVector(Vec& v, CPointChar& cur, size_t& len)
	{
		using ElementType = typename Vec::value_type;
		uint32_t vecLen;
		L_COND(Unpack(vecLen, cur, len), false);
		v.resize(vecLen);
		if constexpr (std::is_class<ElementType>::value)
		{
			for (uint32_t i = 0; i < vecLen; i++)
			{
				L_COND(Unpack(v[i], cur, len), false);
			}
		}
		else//基础类型，整块内存复制
		{
			if (vecLen > 0)
			{
				const size_t vecByteNum = sizeof(ElementType) * vecLen;
				L_COND(len >= vecByteNum, false);
				memcpy(&v[0], cur, vecByteNum);
				cur += vecByteNum;
				len -= vecByteNum;
			}
		}
		return true;
	}

	template<class Map>
	inline bool PackMap(const Map& v, PointChar& cur, size_t& len)
	{
		uint32_t cntLen = v.size();
		L_COND(Pack(cntLen, cur, len), false);
		for (const auto& vt : v)
		{
			L_COND(Pack(vt.first, cur, len), false);
			L_COND(Pack(vt.second, cur, len), false);
		}
		return true;
	}

	template<class Map>
	inline bool UnpackMap(Map& v, CPointChar& cur, size_t& len)
	{
		uint32_t cntLen;
		L_COND(Unpack(cntLen, cur, len), false);
		for (uint32_t i = 0; i < cntLen; i++)
		{
			typename Map::key_type k;
			typename Map::mapped_type value;
			L_COND(Unpack(k, cur, len), false);
			L_COND(Unpack(value, cur, len), false);
			v.insert({k, value});
		}
		return true;
	}

#define DEF_PACK_MAP(K,T)\
	template<>\
	inline bool Pack<std::map<K,T>>(const std::map<K,T> &v, PointChar &cur, size_t &len)\
	{\
		return PackMap(v, cur, len);\
	}\
	template<>\
	inline bool Unpack<std::map<K,T>>(std::map<K,T> &v, CPointChar &cur, size_t &len)\
	{\
		return UnpackMap(v, cur, len);\
	}\


	DEF_PACK_MAP(uint32_t, uint32_t)
	DEF_PACK_MAP(uint32_t, uint64_t)
	DEF_PACK_MAP(uint64_t, uint64_t)
	DEF_PACK_MAP(std::string, uint32_t)
	DEF_PACK_MAP(std::string, int32_t)

		///////////////////////unordered_map////////////////////////////
					//定义所有unordered_map<xx>
#define DEF_PACK_UNORDERED_MAP(K,T)\
	template<>\
	inline bool Pack<std::unordered_map<K,T>>(const std::unordered_map<K,T> &v, PointChar &cur, size_t &len)\
	{\
		return PackMap(v, cur, len);\
	}\
	template<>\
	inline bool Unpack<std::unordered_map<K,T>>(std::unordered_map<K,T> &v, CPointChar &cur, size_t &len)\
	{\
		return UnpackMap(v, cur, len);\
	}\

			//实际情况少量使用，需要再扩展
	DEF_PACK_UNORDERED_MAP(uint32_t, uint32_t)
	DEF_PACK_UNORDERED_MAP(uint32_t, uint64_t)
	DEF_PACK_UNORDERED_MAP(uint64_t, uint64_t)
	DEF_PACK_UNORDERED_MAP(std::string, uint32_t)
	DEF_PACK_UNORDERED_MAP(std::string, int32_t)

	///////////////////////vector////////////////////////////
	//定义所有vector<xx>  
	//觉得理论上不应该每种vector<xx>都定义，应该有方法会静态识别vector类型，并调用PackVector函数，不需要这里得定义。
	//但还没研究出方法，先用宏吧所有情况实现一遍
#define DEF_PACK_VEC(T)\
	template<>\
	inline bool Pack<std::vector<T>>(const std::vector<T> &v, PointChar &cur, size_t &len)\
	{\
		return PackVector(v, cur, len);\
	}\
	template<>\
	inline bool Unpack<std::vector<T>>(std::vector<T> &v, CPointChar &cur, size_t &len)\
	{\
		return UnpackVector(v, cur, len);\
	}\

	DEF_PACK_VEC(int32_t)
	DEF_PACK_VEC(uint32_t)
	DEF_PACK_VEC(int64_t)
	DEF_PACK_VEC(uint64_t)
	DEF_PACK_VEC(double)
	DEF_PACK_VEC(int16_t)
	DEF_PACK_VEC(uint16_t)
	DEF_PACK_VEC(int8_t)
	DEF_PACK_VEC(uint8_t)
	DEF_PACK_VEC(std::string)


#if 0
		参考代码（未研究完整），可考虑代替 上面写法
		LDEBUG("%d", std::is_class<int>::value);
	LDEBUG("%d", std::is_class<vector<int32>>::value);
		template<class T>
	struct PackTypeTrait
	{
		using value_type = T::value_type;
	};

	template<>
	struct PackTypeTrait<int32>
	{
		using value_type = int32;
	};

	template<class T, class T2 = PackTypeTrait<T>::value_type>
	inline bool Pack(const T& v)
	{
		return true;
	}

	template<>
	inline bool Pack<int32>(const int32& v)
	{
		return true;
	}

	template<>
	inline bool Pack<std::vector<int32>>(const std::vector<int32>& v)
	{
		return true;
	}

	int main()
	{
		vector<int32> vec;
		//Pack(3);
		Pack(vec);
#endif // 0


}




#define PACK_FIELD(fieldName)  L_COND(Pack(v.fieldName, cur, len), false);
#define UNPACK_FIELD(fieldName)  L_COND(Unpack(v.fieldName, cur, len), false);
#define UNPACK_FIELD_EXTEND(fieldName)  L_COND(Unpack(v.fieldName, cur, len), false); unpackNum++; if (unpackNum >= num) { return true; }
#define CHECK_DEF_MEMBER(fieldName) decltype(CheckType::fieldName) fieldName;
#define CHECK_FIELD_ORDER(fieldName)	\
					{\
						size_t offset = (size_t)&(((decltype(t) *)(nullptr))->fieldName);\
						if(lastOffset > offset)\
						{\
							L_ERROR("field "#fieldName" define order is error");\
						}\
						lastOffset = offset;\
					}\


//域的顺序 和 遗漏，都会第一次Pack的时候检查出来
#define REFLECTION(className, ...)  \
	template<>\
	inline bool Pack<className>(const className &v, PointChar &cur, size_t &len)\
	{\
		static StaticRunFun check([](){\
			struct Check_##className \
			{\
				using CheckType = className;\
				MAKE_ARG_LIST(CHECK_DEF_MEMBER, __VA_ARGS__);\
			};\
			if (sizeof(Check_##className) != sizeof(className))\
			  {\
					L_ERROR(#className" miss field define!");\
					L_ASSERT(false);\
			  }\
\
			{\
				className t;\
				size_t lastOffset = 0; \
				MAKE_ARG_LIST(CHECK_FIELD_ORDER, __VA_ARGS__);\
			}\
		});\
\
		MAKE_ARG_LIST(PACK_FIELD, __VA_ARGS__);\
		return true;\
	}\
	template<>\
	inline bool Pack<className>(const className& v, std::string& str)\
	{\
		str.resize(1024 * 1024 * 1); \
		char* cur = const_cast<char*>(str.c_str()); \
		size_t len = str.length(); \
		if (!Pack(v, cur, len))\
		{\
			return false; \
		}\
		str.resize(str.length()-len); \
		return true; \
	}\
	template<>\
	inline bool Unpack<className>(className &v, CPointChar &cur, size_t &len)\
	{\
		MAKE_ARG_LIST(UNPACK_FIELD, __VA_ARGS__);\
		return true;\
	}\
	template<>\
	inline bool Unpack<className>(className& v, const std::string& str)\
	{\
		if (str.empty()){return true;}\
		const char* cur = str.c_str();\
		size_t len = str.length();\
		return Unpack(v, cur, len);\
	}\
	DEF_PACK_VEC(className)\
	DEF_PACK_MAP(uint64_t, className)\
	DEF_PACK_MAP(uint32_t, className)\
	DEF_PACK_UNORDERED_MAP(uint64_t, className)\
	DEF_PACK_UNORDERED_MAP(uint32_t, className)\


// 在 REFLECTION 功能的基础上，增加结构体扩展功能。 
//比如操作顺序： 旧结构体打包为字符串s1，新结构体增加字段（不能删除）， 解包s1到新结构体，新增字段取默认值。
#define REFLECTION_EXTEND(className, ...)  \
	template<>\
	inline bool Pack<className>(const className &v, PointChar &cur, size_t &len)\
	{\
		static StaticRunFun check([](){\
			struct Check_##className \
			{\
				using CheckType = className;\
				MAKE_ARG_LIST(CHECK_DEF_MEMBER, __VA_ARGS__);\
			};\
			if (sizeof(Check_##className) != sizeof(className))\
			  {\
					L_ERROR(#className" miss field define!");\
					L_ASSERT(false);\
			  }\
\
			{\
				className t;\
				size_t lastOffset = 0; \
				MAKE_ARG_LIST(CHECK_FIELD_ORDER, __VA_ARGS__);\
			}\
		});\
\
		uint8_t num = GET_ARG_COUNT(__VA_ARGS__);\
		L_COND(Pack(num, cur, len), false);\
		MAKE_ARG_LIST(PACK_FIELD, __VA_ARGS__);\
		return true;\
	}\
	template<>\
	inline bool Pack<className>(const className& v, std::string& str)\
	{\
		str.resize(1024 * 1024 * 1); \
		char* cur = const_cast<char*>(str.c_str()); \
		size_t len = str.length(); \
		if (!Pack(v, cur, len))\
		{\
			return false; \
		}\
		str.resize(str.length()-len); \
		return true; \
	}\
	template<>\
	inline bool Unpack<className>(className &v, CPointChar &cur, size_t &len)\
	{\
		uint8_t num = 0;\
		uint8_t unpackNum = 0;\
		L_COND(Unpack(num, cur, len), false);\
		MAKE_ARG_LIST(UNPACK_FIELD_EXTEND, __VA_ARGS__);\
		return true;\
	}\
	template<>\
	inline bool Unpack<className>(className& v, const std::string& str)\
	{\
		if (str.empty()){return true;}\
		const char* cur = str.c_str();\
		size_t len = str.length();\
		return Unpack(v, cur, len);\
	}\
	DEF_PACK_VEC(className)\
	DEF_PACK_MAP(uint64_t, className)\
	DEF_PACK_MAP(uint32_t, className)\
	DEF_PACK_UNORDERED_MAP(uint64_t, className)\
	DEF_PACK_UNORDERED_MAP(uint32_t, className)\


#if 0 // REFLECTION_EXTEND(className, m1, m2) 展开代码
template<>
inline bool Pack<className>(const className& v, PointChar& cur, size_t& len)
{
	static StaticRunFun check([]() { //错误检查
		struct Check_##className
		{
			using CheckType = className;
			decltype(CheckType::m1) m1;
			decltype(CheckType::m2) m2;
		};
		if (sizeof(Check_##className) != sizeof(className))
		{
			L_ERROR(#className" miss field define!");
			L_ASSERT(false);
		}
		{
			className t;
			size_t lastOffset = 0;
			{
				size_t offset = (size_t) & (((decltype(t)*)(nullptr))->m1);
				if (lastOffset > offset)
				{
					L_ERROR("field m1 define order is error");
				}
				lastOffset = offset; 
			}
		}
		//m2 ...
	});

	uint8_t num = GET_ARG_COUNT(__VA_ARGS__);
	L_COND(Pack(num, cur, len), false);

	L_COND(Pack(v.m1, cur, len), false);
	L_COND(Pack(v.m2, cur, len), false);
	return true;
}

template<>
inline bool Pack<className>(const className& v, std::string& str)
{
	str.resize(1024*1024*1);
	char* cur = const_cast<char*>(str.c_str());
	size_t len = str.length();
	if (!Pack(v, cur, len))
	{
		return false;
	}
	str.resize(len);
	return true;
}

template<>
inline bool Unpack<className>(className& v, CPointChar& cur, size_t& len)
{
	uint8_t num = 0;
	uint8_t unpackNum = 0;
	L_COND(Unpack(num, cur, len), false);
	L_COND(Unpack(v.m1, cur, len), false); unpackNum++; if (unpackNum >= num) { return true; }
	L_COND(Unpack(v.m2, cur, len), false); unpackNum++; if (unpackNum >= num) { return true; }
	return true;
}
template<>
inline bool Unpack<className>(className& v, const std::string& str)
{
	const char* cur = str.c_str();
	size_t len = str.length();
	return Unpack(v, cur, len);
}



//下面定义各种 className 在容器的打包解包
	DEF_PACK_VEC(className)
	DEF_PACK_MAP(uint64_t, className)
	DEF_PACK_MAP(uint32_t, className)
	DEF_PACK_UNORDERED_MAP(uint64_t, className)
	DEF_PACK_UNORDERED_MAP(uint32_t, className)

#endif
